package com.tupu.service.impl.permission;


import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tupu.entity.dto.UserDto;
import com.tupu.entity.permission.OrganizationInfo;
import com.tupu.entity.permission.RoleInfo;
import com.tupu.entity.permission.UserInfo;
import com.tupu.mapper.permission.OrganizationMapper;
import com.tupu.mapper.permission.RoleMapper;
import com.tupu.mapper.permission.UserMapper;
import com.tupu.service.permission.UserService;
import com.tupu.util.TokenUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserInfo> implements UserService {

    @Autowired(required = false)
    private UserMapper userMapper;

    @Autowired(required = false)
    private TokenUtils tokenUtils;

    @Autowired(required = false)
    private UserService userService;

    @Autowired(required = false)
    private RoleMapper roleMapper;

    @Autowired(required = false)
    private OrganizationMapper organizationMapper;

    @Value("${otherSystem.url}")
    private String otherSystemUrl;

    @Value("${file.ipAddress}")
    private String ipAddress;

    @Value("${file.imagesPath}")
    private String imagesPath;

    @Override
    public String register(UserInfo user) {
        UserInfo userExist = userMapper.findUserByName(user.getUserName());
        if (StringUtils.isEmpty(user.getUserName())) {
            return "用户名不能为空";
        } else if (StringUtils.isEmpty(user.getRealName())) {
            return "请确认真实姓名";
        } else if (user.getTelephone() == null) {
            return "请确认密码";
        } else if (user.getCode() == null) {
            return "请确认验证码";
        } else if (user.getPassword() == null) {
            return "密码不能为空";
        } else if (user.getConfirmPassword() == null) {
            return "请确认密码";
        } else if (userExist != null) {
            return "用户已存在";
        } else {
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String format = sdf.format(date);
            user.setUpdateTime(format);
            String password = user.getPassword();
            user.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
            userMapper.insert(user);
            return "注册成功";
        }
    }

    /**
     * 批量删除用户
     *
     * @param ids
     */
    @Override
    public void delUser(List<Integer> ids) {
        for (Integer id : ids) {
            userMapper.deleteById(id);
        }
    }

    /**
     * 从其他系统登录时调用此方法
     *
     * @param otherToken
     * @return
     */
    @Override
    public Map<Object, Object> loginOther(String otherToken) {
        Map<Object, Object> resultMap = new HashMap<>();
        try {
            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.add("Authorization", "Bearer " + otherToken);
            HttpEntity<String> httpEntity = new HttpEntity<>(headers);
            String result = restTemplate.exchange(otherSystemUrl + "/e8820-api/getInfo", HttpMethod.GET, httpEntity, String.class).getBody();
            log.error(result);
            JSONObject jsonObject = JSON.parseObject(result);
            if (jsonObject.getInteger("code") != null && jsonObject.getInteger("code") == 200) {
                JSONObject resultObj = jsonObject.getJSONObject("user");
                String userName = resultObj.getString("userName");
                Map<String, Object> claims = new HashMap<>();
                QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("user_name", userName);
                UserInfo userInfo = userService.getOne(queryWrapper);
                if (userInfo == null) {
                    throw new RuntimeException("获取用户信息出错");
                }
                claims.put("userName", userInfo);
                String token = tokenUtils.generateToken(userInfo.getUserId().toString(), claims);
                resultMap.put("token", token);
                resultMap.put("userName", userName);
            }
        } catch (Exception e) {
            throw new RuntimeException("获取用户信息出错");
        }
        return resultMap;
    }

    @Override
    public Map<String, Object> userNum() {
        Map<String, Object> map = new HashMap<>();
        QueryWrapper<UserInfo> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("status", 2);
        List<UserInfo> addList = userMapper.selectList(queryWrapper1);
        QueryWrapper<UserInfo> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.isNull("role_id");
        queryWrapper2.isNull("organization_id");
        List<UserInfo> setList = userMapper.selectList(queryWrapper2);
        map.put("addNum", addList.size());
        map.put("setNum", setList.size());
        return map;
    }

    @Override
    public void approvalUser(Integer id) {
        UserInfo userInfo = userService.getById(id);
        userInfo.setStatus(1);
        userMapper.updateById(userInfo);
    }

    @Override
    public String updateUser(UserInfo user) {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String format = sdf.format(date);
        user.setUpdateTime(format);
        String reg = "1[3-9]\\d{9}";
        Pattern pattern = Pattern.compile(reg);
        Long telephone = user.getTelephone();
        Integer userId = user.getUserId();
        UserInfo userInfo = userMapper.selectById(userId);
        if (userInfo.getUserName().equals(user.getUserName())) {
            if (!user.getPassword().equals(user.getConfirmPassword())) {
                return "密码输入不一致";
            }
            if (!pattern.matcher(telephone.toString()).matches() && telephone.toString().length() != 11) {
                return "请输入正确的手机号";
            }
            userMapper.updateById(user);
            return "修改成功";
        }
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_name", user.getUserName());
        if (null != userMapper.selectOne(queryWrapper)) {
            return "登录账号已存在";
        }
        if (!user.getPassword().equals(user.getConfirmPassword())) {
            return "密码输入不一致";
        }
        if (!pattern.matcher(telephone.toString()).matches() && telephone.toString().length() != 11) {
            return "请输入正确的手机号";
        }
        userMapper.updateById(user);
        return "修改成功";
    }

    @Override
    public UserDto findOneByUserId(Integer user_id) {
        UserInfo userInfo = userMapper.selectById(user_id);
        UserDto userDto = new UserDto();
        userDto.setUserId(userInfo.getUserId());
        userDto.setUserName(userInfo.getUserName());
        userDto.setSex(userInfo.getSex());
        userDto.setTelephone(userInfo.getTelephone());
        userDto.setStatus(userInfo.getStatus());
        userDto.setImages(ipAddress + userInfo.getImages());
        Integer organizationId = userInfo.getOrganizationId();
        OrganizationInfo organizationInfo = organizationMapper.selectById(organizationId);
        userDto.setOrganization(organizationInfo.getName());
        Integer roleId = userInfo.getRoleId();
        RoleInfo roleInfo = roleMapper.selectById(roleId);
        userDto.setRole(roleInfo.getRoleName());
        return userDto;
    }

    @Override
    public Page<UserDto> pageInfo(Integer page, Integer size, String userName, List<Integer> statusList) {

        Page<UserInfo> pageInfo = new Page<>(page, size);
        Page<UserDto> pageDto = new Page<>(page, size);
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(userName)) {
            queryWrapper.like("user_name", userName);
        }
        if (statusList != null && statusList.size() > 0) {
            queryWrapper.in("status", statusList);
        }
        queryWrapper.orderByAsc("user_id");
        Page<UserInfo> userInfoPage = userMapper.selectPage(pageInfo, queryWrapper);

        pageDto.setTotal(userInfoPage.getTotal()); //总条数
        pageDto.setSize(userInfoPage.getSize());  //每页显示多少条
        pageDto.setCurrent(userInfoPage.getCurrent());
        pageDto.setPages(userInfoPage.getPages());  //总页数
        List<UserInfo> records = userInfoPage.getRecords();
        List<UserDto> userList = new ArrayList<>();
        for (UserInfo user : records) {
            UserDto userDto = new UserDto();
            userDto.setUserId(user.getUserId());
            userDto.setUserName(user.getUserName());
            userDto.setRealName(user.getRealName());
            userDto.setSex(user.getSex());
            userDto.setTelephone(user.getTelephone());
            userDto.setStatus(user.getStatus());
            userDto.setImages(ipAddress + user.getImages());
            Integer organizationId = user.getOrganizationId();
            OrganizationInfo organizationInfo = organizationMapper.selectById(organizationId);
            if (organizationInfo != null) {
                userDto.setOrganization(organizationInfo.getName());
            }
            Integer roleId = user.getRoleId();
            RoleInfo roleInfo = roleMapper.selectById(roleId);
            if (roleInfo != null) {
                userDto.setRole(roleInfo.getRoleName());
            }
            userList.add(userDto);
        }
        pageDto.setRecords(userList); //数据
        return pageDto;
    }

    @Override
    public String addUser(UserInfo user) {
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_name", user.getUserName());
        if (null != userMapper.selectOne(queryWrapper)) {
            return "账号已存在";
        }
        if (!user.getPassword().equals(user.getConfirmPassword())) {
            return "密码输入不一致";
        }
        String reg = "1[3-9]\\d{9}";
        Pattern pattern = Pattern.compile(reg);
        Long telephone = user.getTelephone();
        if (!pattern.matcher(telephone.toString()).matches() && telephone.toString().length() != 11) {
            return "请输入正确的手机号";
        }
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String format = sdf.format(date);
        user.setUpdateTime(format);
        String password = SecureUtil.md5(user.getPassword());
        user.setPassword(password);
        userMapper.insert(user);
        return "添加成功";
    }

    @Override
    public Map<String, Object> UploadPicture(MultipartFile file) throws IOException {
        Map<String, Object> result = new HashMap<>();
        //获取文件的名字
        String originName = file.getOriginalFilename();
        //判断文件类型
        if (!originName.endsWith(".jpg") && !originName.endsWith(".png")) {
            result.put("status", "error");
            result.put("msg", "文件类型不对");
            return result;
        }
        //给上传文件取新的名字+原后缀，避免重名
        String ext = originName.substring(originName.lastIndexOf("."));
        String newName = UUID.randomUUID() + ext;
        // 上传图片到指定文件夹（想存放地址的相对路径）
        //File savePos = new File("/home/images/");
        File savePos = new File(imagesPath);
        /*//给上传的文件新建目录
        String format = sdf.format(new Date());
        String realPath = fileSavePath + format;
        System.out.println("realPath:" + realPath);
                File folder = new File(realPath);*/
        // 若目录不存在则创建目录、创建该文件夹
        if (!savePos.exists()) {
            savePos.mkdir();
        }
        // 获取存放位置的规范路径
        String realPath = savePos.getCanonicalPath();
        // 上传该文件/图像至该文件夹下
        file.transferTo(new File(realPath + "/" + newName));
        //获得本机Ip（获取的是服务器的Ip）
        //InetAddress inetAddress = InetAddress.getLocalHost();
        //String ip = inetAddress.getHostAddress();
        //返回保存的url，根据url可以进行图片查看
        String fileDownloadUrl = "/api/file/" + newName;
        //输出结果
        result.put("status", "success");
        result.put("url", fileDownloadUrl);
        return result;
    }

    @Override
    public Map<String, Object> info(String account) {
        Map<String, Object> map = new HashMap<>();
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_name", account);
        UserInfo userInfo = userService.getOne(queryWrapper);
        map.put("role", userInfo.getRoleId());
        map.put("avatar", userInfo.getImages());
        map.put("name", userInfo.getRealName());
        return map;
    }

    @Override
    public String testUser(UserInfo user) {
        String md5 = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_name", user.getUserName());
        UserInfo userInfo = userMapper.selectOne(queryWrapper);
        if (null == userInfo) {
            return "用户不存在";
        } else if (!md5.equals(userInfo.getPassword())) {
            return "密码错误";
        } else if (userInfo.getStatus() != 1) {
            return "账号未启用";
        }
        return "账号正常";
    }

    @Override
    public Map<String, Object> userLogin(HttpServletRequest request, UserInfo user) {
        Map<String, Object> result = new HashMap<>();
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_name", user.getUserName());
        UserInfo userInfo = userMapper.selectOne(queryWrapper);
        request.getSession().setAttribute("user", userInfo.getUserId());
        Map<String, Object> claims = new HashMap<>();
        claims.put("userName", user.getUserName());
        claims.put("password", user.getPassword());
        String token = tokenUtils.generateToken(userInfo.getUserId().toString(), claims);
        result.put("token", token);
        return result;
    }

}